home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
risc_src.lha
/
risc_sources
/
sys
/
mipskernel.t
< prev
next >
Wrap
Text File
|
1989-06-30
|
16KB
|
409 lines
(herald mipskernel (env tsys))
;;; Copyright (c) 1985 Yale University
;;; Authors: N Adams, R Kelsey, D Kranz, J Philbin, J Rees.
;;; This material was developed by the T Project at the Yale University Computer
;;; Science Department. Permission to copy this software, to redistribute it,
;;; and to use it for any purpose is granted, subject to the following restric-
;;; tions and understandings.
;;; 1. Any copy made of this software must include this copyright notice in full.
;;; 2. Users of this software agree to make their best efforts (a) to return
;;; to the T Project at Yale any improvements or extensions that they make,
;;; so that these may be included in future releases; and (b) to inform
;;; the T Project of noteworthy uses of this software.
;;; 3. All materials developed as a consequence of the use of this software
;;; shall duly acknowledge such use, in accordance with the usual standards
;;; of acknowledging credit in academic research.
;;; 4. Yale has made no warrantee or representation that the operation of
;;; this software will be error-free, and Yale is under no obligation to
;;; provide any services, by way of maintenance, update, or otherwise.
;;; 5. In conjunction with products arising from the use of this material,
;;; there shall be no use of the name of the Yale University nor of any
;;; adaptation thereof in any advertising, promotional, or sales literature
;;; without prior written consent from Yale in each case.
;;;
;;; The procedure big_bang MUST come first in this file.
;;; BIG_BANG is called to instantiate the root process of an external
;;; T image. It is called by a foreign stub program with arguments
;;; as follows:
;;;
;;; (BIG_BANG memory mem-size argc argv bsd4.2?).
;;;
;;; The argument vector is saved as a T vector in *BOOT-ARGS*. The
;;; Xenoids are created for STDIN and STDOUT and placed in the 2nd
;;; and 3rd argument registers. The global-constant register (NIL)
;;; and the task register are initialized, and the root process
;;; block is created and initialized. The stack is initialized.
;;; The heap-pointer and heap-limit of the root process are
;;; initialized. Finally the address of the T procedure BOOT is
;;; placed in them P (procedure) register, and we jump through the
;;; root process block to ICALL. Boot is called as follows:
;;;
;;; (BOOT root-task boot-args),
;;; Unresolved issues:
;;; - Is the arg vector the right size and is the descriptor correct?
;;; - What should the initial stack size be and how can you tell?
;;; - The stack and areas should have guards - later I guess
;;; - how to boot other systems
;;; - stdio shit?
;;; - PID as Fixnum?
;;; - *the-slink*
;;; - test stack-overflow in icall?
;;; - heap overflow code
;;; - exception code
;;; - interrupt code
;;; When we enter Big_bang the stack looks as follows:
;;;
;;; | debug? |
;;; |_______________|
;;; | argv | Command line argv
;;; |_______________|
;;; | argc | Command line argc
;;; |_______________|
;;; | heap-size |
;;; |_______________|
;;; | heap2 |
;;; |_______________|
;;; | heap1 |
;;; |_______________|
;;; SP => | dummy |
;;; |_______________|
;;; | header | <= *boot-args*
;;; |_______________|
(define (big_bang)
(lap (*boot* *the-slink* risc-big-bang)
;; set up global-constants
(move zero crit-reg)
(move ($ header/true) t-reg)
(load l (d@r P (static *the-slink*)) extra)
(load l (d@r extra 2) nil-reg)
(sub ($ 3) nil-reg sp) ;grows down to data bottom 512K
(sll ($ 2) scratch)
(store l scratch (d@nil slink/interrupt-handler)) ; interrupt_xenoid
(store l a2 (d@r ssp 0)) ;heap1 a2=$4
(store l a3 (d@r ssp 4)) ;heap2
(store l a4 (d@r ssp 8)) ;heap-size
(store l a5 (d@r ssp 12)) ;argc
(move SSP A1) ; save argument pointer
(sub ($ 8) ssp) ;dummy,header
(movec (fx+ (fixnum-ashl 6 8) header/general-vector) extra)
(store l extra (d@r ssp 0))
(add ($ 2) ssp a2)
(store l A2 (d@nil slink/boot-args)) ; we have 6 boot-args
(load l (d@r P (static risc-big-bang)) P)
(load l (d@r p 2) p)
(load l (d@r P -2) extra)
(add ($ 2) extra)
(jalr extra)
(noop)
;; initialize area, area-frontier, and area-limit
(load l (d@r A1 0) scratch) ; move addr heap
(store l scratch (d@nil slink/area-begin))
(store l scratch (d@nil slink/area-frontier))
(load l (d@r A1 8) vector)
(add vector scratch)
(store l scratch (d@nil slink/area-limit))
;; Set up the procedure register P and call boot,
;; never to return. (note: args 2 was setup above)
(move nil-reg A3)
(load l (d@r a1 20) extra)
(j= extra zero %debug)
(move t-reg A3)
%debug
(load l (d@r P (static *boot*)) P)
(load l (d@r p 2) p)
(load l (d@r P -2) extra)
(add ($ 2) extra)
(jr extra)
(move ($ 4) NARGS)))
;;;; Low-level exception handling
#|
(lap-template (0 0 -1 t stack %fault-frame-handler)
%fault-frame-template
(bisb2 ($ #b01000000) (d@r task (fx+ task/critical-count 3)))
(ashl ($ -8) (d@r SP 4) S0) ; fault header
(addl2 ($ 2) S0) ; 2 for header and template
(tstl (d@r SP 12))
(j= foobar)
(movl (d@r SP 12) (index (@r SP) S0)) ; restore hacked top of stack
foobar
(addl2 ($ 16) sp) ; pop template,header,pointers on stack,hack top
(movl (d@r SP (* (+ *pointer-temps* *scratch-temps* 10) 4))
A1) ; context
(movl (@r+ SP) (d@r A1 %%df_pc))
(movl (@r+ SP) (d@r A1 %%df_r4)) ; P
(movl (@r+ SP) (d@r A1 %%df_r5)) ; A1
(movl (@r+ SP) (d@r A1 %%df_r6)) ; A2
(movl (@r+ SP) (d@r A1 %%df_r7)) ; A3
(movl (@r+ SP) (d@r A1 %%df_r8)) ; A4
(movl (@r+ SP) (d@r A1 %%df_r9)) ; AN
(movl (@r+ SP) (d@r A1 %%df_r10)) ; TP
(movl ($ -2) S0)
%fault-restore-loop ; restore temps
(movl (@r+ SP) (index (@r TASK) S0))
(incl S0)
(cmpl ($ (fx/ temp-block-size 4)) S0)
(j> %fault-restore-loop)
(addl2 ($ 4) SP) ; pop context
(bicb2 ($ #b01000000) (d@r task (fx+ task/critical-count 3)))
(rsb)
%fault-frame-handler
(movl nil-reg an)
(rsb))
(lap-template (0 0 -1 nil stack handle-foreign-return)
%foreign-return
(bisb2 ($ #b01000000) (d@r task (fx+ task/critical-count 3)))
(addl2 ($ 8) sp) ; pop template,header
(movl (@r+ SP) (d@r TASK task/foreign-call-cont))
(bicb2 ($ #b01000000) (d@r task (fx+ task/critical-count 3)))
(rsb)
handle-foreign-return
(movl nil-reg AN)
(rsb))
(lap-template (0 0 -1 nil stack handle-enable-return)
%re-enabled
(addl2 ($ 4) sp) ; pop return address
(rsb)
handle-enable-return
(movl nil-reg AN)
(rsb))
(lap-template (0 0 -1 nil stack handle-doing-gc-return)
%doing-gc-return
(addl2 ($ 4) sp) ; pop return address
(rsb)
handle-doing-gc-return
(movl nil-reg AN)
(rsb))
;;; Interrupts can be deferred.
;;; the task/critical count byte has
;;; bit 7 -- interrupts deferred
;;; bit 6 -- interrupts ignored
;;; bit 1 -- quit pending
;;; bit 0 -- timer interrupt pending
|#
(define (interrupt_dispatcher) ; arg pointer is AN
(lap (signal-handler enable-signals gc_interrupt)
(move ($ -1) extra)
(jr extra)
(noop)))
#|
(equate %%fault-sp-offset 8)
(equate %%df_r4 -36) ; P
(equate %%df_r5 -32) : a1
(equate %%df_r6 -112) ; a2
(equate %%df_r7 -108) ; a3
(equate %%df_r8 -104) ; a4
(equate %%df_r9 -100) ; an
(equate %%df_r10 -96) ; tp
(equate %%df_pc 12)
(equate fault-quit 3)
(equate fault-interrupt 2)
(equate fault-virtual-timer 26)
(movl (d@r AN 4) A4) ; get signal code
(movl (d@r nil-reg slink/current-task) task) ; restore task
(bbs ($ 6) (d@r task (fx+ task/critical-count 3)) (to %ignore-interrupt))
(movl (d@r AN 12) AN) ; get context
(cmpl ($ fault-virtual-timer) A4) ; is this a timer interrupt?
(j= %timer)
(cmpl ($ fault-interrupt) A4) ; is this a ^q?
(jn= %fault) ; if so ..
(cmpl (d@r TASK task/doing-gc?) nil-reg) ; are we doing gc?
(jn= %doing-gc) ; if not ...
(tstl (d@r TASK task/foreign-call-cont))
(jn= %fault)
(bitb ($ 2) (d@r TASK (fx+ task/critical-count 3))) ; is this the second one?
(j= %set-interrupt-flag) ; if not, defer interrupt
(bicb2 ($ 2) (d@r TASK (fx+ task/critical-count 3)))
(tstb (d@r TASK (fx+ task/critical-count 3))) ; are interrupts deferred?
(j= %fault) ; if so ...
%set-interrupt-flag
(bisb2 ($ 2) (d@r TASK (fx+ task/critical-count 3))) ; set quit bit
(jmp (label %ignore-interrupt))
%timer
(cmpl (d@r TASK task/doing-gc?) nil-reg) ; are we doing gc?
(jn= %ignore-interrupt)
(tstb (d@r TASK (fx+ task/critical-count 3)))
(j= %fault)
(bisb2 ($ 1) (d@r TASK (fx+ task/critical-count 3))) ; set timer bit
%ignore-interrupt
(pushal (label %re-enabled)) ; re-enable interrupts
(movl (d@r p (static 'enable-signals)) p) ; DON'T CONS!!!
(movl (d@r p 2) p)
(movl (d@r p -2) tp)
(jmp (@r tp))
%doing-gc
(pushal (label %doing-gc-return))
(movl (d@r p (static 'gc_interrupt)) p)
(movl (d@r p 2) p)
(movl (d@r p -2) tp)
(jmp (@r tp))
;;; Interrupts should be disabled here.
%fault
(movl (d@r task task/foreign-call-cont) S1)
(j= %t-code-interrupt)
;; Interrupted out of foreign code.
(clrl (d@r task task/foreign-call-cont))
(pushl s1) ; push foreign continuation
(subl2 sp s1) ; compute frame size
(ashl ($ 6) S1 S1)
(movb ($ (fx+ header/fault-frame 128)) S1)
(pushl s1) ; push frame size
(pushal (label %foreign-return))
(jmp (label %fault-done))
;;; registers s0=fault-sp aN=context
%t-code-interrupt
(pushl AN) ; save context
(movl (d@r AN %%fault-sp-offset) S0) ; get fault SP in S0
(movl S0 A1) ; save fault sp
(movl ($ (fx/ (fx+ temp-block-size 4) 4)) S2)
%fault-save-loop ; save temps and extra p and s
(pushl (index (d@r TASK -8) S2))
(decl S2)
(j>= %fault-save-loop)
(pushl (d@r AN %%df_r10)) ; TP
(pushl (d@r AN %%df_r9)) ; AN
(pushl (d@r AN %%df_r8)) ; A4
(pushl (d@r AN %%df_r7)) ; A3
(pushl (d@r AN %%df_r9)) ; A2
(pushl (d@r AN %%df_r5)) ; A1
(pushl (d@r AN %%df_r4)) ; P
(movl (d@r AN %%df_pc) S1)
(pushl S1)
(cmpl (d@r nil-reg slink/kernel-begin) S1)
(j> %not-in-kernel)
(cmpl (d@r nil-reg slink/kernel-end) S1)
(j< %not-in-kernel)
(pushl (@r A1)) ; save hack top of stack
(pushl ($ 0)) ; no pointers on top
(jmp (label %t-code-done))
%not-in-kernel
(pushl ($ 0)) ; no hacked stack top
;;; find how many pointers on top of stack
(mnegl ($ 1) s1) ; pointer slot counter as fixnum
%find-last-template-loop
(incl s1) ; incr # pointer counter
(movl (@r+ a1) s2) ; load next word
(cmpb ($ header/vframe) s2) ; vframe?
(j= %found-frame) ; .. if so, done looking
(bicb3 ($ #b11111100) s2 s3) ; copy for extend test
(cmpb ($ tag/extend) s3) ; extend?
(jn= %find-last-template-loop) ; .. if not, keep looking
(cmpb ($ header/template) (d@r s2 -2)) ; fetch template
(jn= %find-last-template-loop) ; .. if high bit is 0, keep looking
%found-frame
(ashl ($ 2) s1 (@-r SP)) ; push number of pointers on stack
%t-code-done
(subl2 sp s0) ; compute total size of frame
(ashl ($ 6) s0 s0)
(movb ($ header/fault-frame) s0)
(pushl s0) ; push fault header
(pushal (label %fault-frame-template)) ; call fault handler
%fault-done
(ashl ($ 2) A4 a1) ; 1st argument is signal code
(moval (d@r SP 6) a2) ; 2nd argument is frame
(movl (d@r p (static 'signal-handler)) p) ; ...
(movl (d@r p 2) p)
(movl (d@r p -2) tp) ; ...
(jmp (@r tp)) ; ...
))
|#
(define local-processor
(lambda ()
(object nil
((processor-type self) 'mips)
((print-type-string self) "Processor"))))
(define (local-machine)
(object nil
((machine-type self) 'mipsco)
((page-size self) 512)
((machine-suspend-file self) '(link mipssuspend))
((object-file-type self) 'mpo)
((information-file-type self) 'mpi)
((noise-file-type self) 'mpn)
((print-type-string self) "Machine")))
(define (nan? x) (ignore x) '#f)
(define (st_mtime stat-block)
(+ (ash (mref-16-u stat-block 34) 16)
(mref-16-u stat-block 32)))
(define-integrable (st_size stat-block)
(mref-integer stat-block 20))
(define-integrable (st_mode stat-block)
(mref-16-u stat-block 8))
(define-constant %%apollo-d-ieee-size 53)
(define-constant %%apollo-d-ieee-excess 1023)
;;; <n,s> means bit field of length s beginning at bit n of the first
;;; WORD (not longword)
;;; sign exponent MSB fraction
;;; IEEE flonum <15,1> <4,11> hidden <0,4>+next 3 words
;;; VAX11 flonum (D) <15,1> <7,8> hidden <0,7>+next 3 words
(define (integer-decode-float x) ; IEEE version
(let ((a (mref-16-u x 0)))
(return (if (fl<= 0.0 x) 1 -1)
(+ (mref-16-u x 6)
(%ash (+ (mref-16-u x 4)
(%ash (fx+ (mref-16-u x 2)
(fixnum-ashl (fx+ (fixnum-bit-field a 0 4) 16)
16))
16))
16))
(fx- (fixnum-bit-field a 4 11) (fx+ 1024 51)))))
(define (integer-encode-float sign m e)
(let ((float (make-flonum)))
(receive (sign mantissa exponent)
(normalize-float-parts sign
m
e
%%apollo-d-ieee-size
%%apollo-d-ieee-excess
t)
(set (mref-16-u float 0) (fx+ (fixnum-ashl sign 15)
(fx+ (fixnum-ashl exponent 4)
(bignum-bit-field mantissa 48 4))))
(set (mref-16-u float 2) (bignum-bit-field mantissa 32 16))
(set (mref-16-u float 4) (bignum-bit-field mantissa 16 16))
(set (mref-16-u float 6) (bignum-bit-field mantissa 0 16))
float)))